using MediatR;
using Microsoft.EntityFrameworkCore;
using SupplierCustomerManagement.Infrastructure;
using SupplierCustomerManagement.Read.API.Applications.Commands.lambing;
using SupplierCustomerManagement.Read.API.Dtos.Lambing;

namespace SupplierCustomerManagement.Read.API.Applications.CommandHandlters.lambing
{
    public class GetParityStructureStatsQueryHandler : IRequestHandler<GetParityStructureStatsQuery, List<ParityStatsPointDto>>
    {
        private readonly SupplierDbContext _db;
        private readonly ILogger<GetParityStructureStatsQueryHandler> _logger;

        public GetParityStructureStatsQueryHandler(SupplierDbContext db, ILogger<GetParityStructureStatsQueryHandler> logger)
        {
            _db = db;
            _logger = logger;
        }

        public async Task<List<ParityStatsPointDto>> Handle(GetParityStructureStatsQuery request, CancellationToken cancellationToken)
        {
            if (!int.TryParse(request.year, out var year))
            {
                year = DateTime.UtcNow.Year;
            }

            // 拉取相关记录（为计算总胎次，需要按母羊维度查看全部历史记录，但可按 farmId 先过滤）
            var baseQuery = _db.LambingRecords.AsNoTracking();
            if (request.farmId.HasValue)
            {
                var fid = request.farmId.Value;
                baseQuery = baseQuery.Where(r => r.FarmId == fid);
            }

            var records = await baseQuery
                .Select(r => new
                {
                    r.EweId,
                    r.LambingDate,
                    r.TotalLambs,
                    r.LiveLambs,
                    r.HealthyLambs,
                    r.WeakLambs,
                    r.DeformedLambs,
                    r.MummifiedFetuses,
                    r.AbnormalFetuses,
                    r.DeadLambs
                })
                .OrderBy(r => r.EweId).ThenBy(r => r.LambingDate)
                .ToListAsync(cancellationToken);

            // 计算每条记录的“总胎次序号”（该母羊历史分娩第几胎，从1开始）。
            var recordsWithParity = new List<(int parity, int year, int total, int? healthy, int? weak, int? deformed, int? mummy, int? abnormal, int dead)>();
            int? currentEwe = null;
            int parityCounter = 0;
            foreach (var r in records)
            {
                if (currentEwe != r.EweId)
                {
                    currentEwe = r.EweId;
                    parityCounter = 0;
                }
                parityCounter += 1; // 第几胎
                recordsWithParity.Add((parityCounter, r.LambingDate.Year, r.TotalLambs, r.HealthyLambs, r.WeakLambs, r.DeformedLambs, r.MummifiedFetuses, r.AbnormalFetuses, r.DeadLambs));
            }

            // 仅统计指定年份发生的分娩记录
            var currentYear = recordsWithParity.Where(x => x.year == year).ToList();

            // 按胎次分桶：0胎（无分娩，暂无数据，设为0），1胎..4胎，5胎代表≥5
            var buckets = new Dictionary<string, List<(int total, int? healthy, int? weak, int? deformed, int? mummy, int? abnormal, int dead)>>
            {
                {"0胎", new() },
                {"1胎", new() },
                {"2胎", new() },
                {"3胎", new() },
                {"4胎", new() },
                {"5胎", new() } // ≥5
            };

            foreach (var x in currentYear)
            {
                string label = x.parity switch
                {
                    1 => "1胎",
                    2 => "2胎",
                    3 => "3胎",
                    4 => "4胎",
                    _ => "5胎"
                };
                buckets[label].Add((x.total, x.healthy, x.weak, x.deformed, x.mummy, x.abnormal, x.dead));
            }

            decimal Avg(IEnumerable<int> seq) => seq.Any() ? Math.Round((decimal)seq.Average(), 3) : 0m;
            decimal AvgN(IEnumerable<int?> seq) => seq.Any() ? Math.Round((decimal)seq.Where(v => v.HasValue).Select(v => v!.Value).DefaultIfEmpty(0).Average(), 3) : 0m;

            var result = new List<ParityStatsPointDto>();
            foreach (var kv in buckets)
            {
                var arr = kv.Value;
                var point = new ParityStatsPointDto
                {
                    parityLabel = kv.Key,
                    avgTotalLamb = Avg(arr.Select(a => a.total)),
                    avgHealthy = AvgN(arr.Select(a => a.healthy)),
                    avgWeak = AvgN(arr.Select(a => a.weak)),
                    avgDeformed = AvgN(arr.Select(a => a.deformed)),
                    avgStillbirth = Avg(arr.Select(a => a.dead)),
                    avgMummy = AvgN(arr.Select(a => a.mummy)),
                    avgAbnormal = AvgN(arr.Select(a => a.abnormal)),
                    deliveryCount = arr.Count,
                    breedingCount = 0
                };
                result.Add(point);
            }

            // 保持顺序 0-5
            var order = new[] { "0胎", "1胎", "2胎", "3胎", "4胎", "5胎" };
            return result.OrderBy(p => Array.IndexOf(order, p.parityLabel)).ToList();
        }
    }
}
